package com.itdog.shader_load

import android.opengl.GLES30
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer

class Triangle {

    private val vertexShaderCode = """
        attribute vec4 vPosition;
        void main() {
            gl_Position = vPosition;
        }
    """.trimIndent()

    private val fragmentShaderCode = """
        precision mediump float;
        uniform vec4 vColor;
        void main() {
            gl_FragColor = vColor;
        }
    """.trimIndent()

    private val triangleCoords = floatArrayOf(
        .0f, .5f, .0f, // 顶部
        -.5f, .0f, .0f, // 左下角
        .5f, .0f, .0f // 右下角
    )

    private val color = floatArrayOf(.5f, .5f, .5f, 0.0f)

    private lateinit var vertexBuffer: FloatBuffer
    private var mPositionHandle = 0
    private var mColorHandle = 0

    private var mProgram: Int = 0

    constructor() {
        // 在GPU中开辟一段数据，把顶点数据放进去
        val bb = ByteBuffer.allocateDirect(triangleCoords.size * 4)
        bb.order(ByteOrder.nativeOrder())
        vertexBuffer = bb.asFloatBuffer()
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0)

        // 创建Shader，并为其指定源码
        val vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertexShaderCode)
        val fragShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragmentShaderCode)

        // 创建OpenGL程序
        mProgram = GLES30.glCreateProgram()
        // 绑定Shader到OpenGL程序
        GLES30.glAttachShader(mProgram, vertexShader)
        GLES30.glAttachShader(mProgram, fragShader)
        // 链接OpenGL程序
        GLES30.glLinkProgram(mProgram)
    }

    fun draw() {
        // 使用Program
        GLES30.glUseProgram(mProgram)

        // 将顶点数据和片元数据传递给Shader的属性变量和Uniform变量
        mPositionHandle = GLES30.glGetAttribLocation(mProgram, "vPosition")
        GLES30.glEnableVertexAttribArray(mPositionHandle)
        GLES30.glVertexAttribPointer(mPositionHandle, 3 /* 坐标个数，二维坐标传2，三维坐标传3*/, GLES30.GL_FLOAT, false, 0, vertexBuffer)

        mColorHandle = GLES30.glGetUniformLocation(mProgram, "vColor")
        GLES30.glUniform4fv(mColorHandle, 1, color, 0)

        // drawArray 绘制三角形
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, triangleCoords.size / 3)
        GLES30.glDisableVertexAttribArray(mPositionHandle)
    }

    private fun loadShader(shaderType: Int, shaderCode: String) : Int {
        // 创建shader对象
        val shader = GLES30.glCreateShader(shaderType)
        // 指定Shader源码
        GLES30.glShaderSource(shader, shaderCode)
        // 编译Shader程序
        GLES30.glCompileShader(shader)
        return shader
    }


}